package com.zt.dev.semiPhysicalEquipment.service.impl;

import com.zt.dev.semiPhysicalEquipment.mapper.SemiPhysicalEquipmentMapper;
import com.zt.dev.semiPhysicalEquipment.pojo.*;
import com.zt.dev.semiPhysicalEquipment.service.SemiPhysicalEquipmentService;
import com.zt.dev.semiPhysicalEquipment.util.ExcelUtils;
import com.zt.dev.semiPhysicalEquipment.util.PageBean;
import lombok.SneakyThrows;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.zt.dev.semiPhysicalEquipment.util.StrUtils.strToArry;

@Service
public class SemiPhysicalEquipmentServiceImpl implements SemiPhysicalEquipmentService {

    private final static String title = "半实物装备信息";

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private SemiPhysicalEquipmentMapper hardWareMapper;

    @Override
    public Boolean hardWareRegist(SemiPhysicalEquipmentInfo semiPhysicalEquipmentInfo) {
        int c = 0;
        //半实物装备信息入库
        c += hardWareMapper.hardWareRegist(semiPhysicalEquipmentInfo);
        Integer equipmentId = semiPhysicalEquipmentInfo.getId();
        //使用信息入库
        List<SemiPhysicalUseInfo> useInfos = semiPhysicalEquipmentInfo.getUseInfos();
        for (SemiPhysicalUseInfo useInfo : useInfos) {
            useInfo.setEquipInfoId(equipmentId);
            c += hardWareMapper.insertUseInfo(useInfo);
        }
        //装备性能值入库
        List<SemiPhysicalPerformanceValue> performances = semiPhysicalEquipmentInfo.getPerformances();
        for (SemiPhysicalPerformanceValue performance : performances) {
            performance.setEquipInfoId(equipmentId);
            c += hardWareMapper.insertPerformances(performance);
        }
        if (c == 0) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public Boolean copyHardWare(String ids) {
        int[] a = strToArry(ids);
        int c = 0;
        for (int id : a) {
            SemiPhysicalEquipmentInfo equipmentInfo = hardWareMapper.findHardWareById(id);
            //装备信息入库
            c += hardWareMapper.hardWareRegist(equipmentInfo);
            //获取装备使用信息列表
            List<SemiPhysicalUseInfo> useInfos = hardWareMapper.findAllUseInfo(id);
            for (SemiPhysicalUseInfo useInfo : useInfos) {
                useInfo.setEquipInfoId(equipmentInfo.getId());
                c += hardWareMapper.insertUseInfo(useInfo);
            }
            //获取装备性能值列表
            List<SemiPhysicalPerformanceValue> values = hardWareMapper.findAllPerformanceVal(id);
            //性能入库
            for (SemiPhysicalPerformanceValue value : values) {
                value.setEquipInfoId(equipmentInfo.getId());
                c += hardWareMapper.insertPerformances(value);
            }
        }
        if (c == 0) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public PageBean<SemiPhysicalEquipmentInfo> findAllHardWare(int currentPage, int pageSize, Integer equipmentId) {
        int count = hardWareMapper.getCount(equipmentId);
        PageBean pageBean = PageBean.pageCommon(count, currentPage, pageSize);
        //起始 结束 页
        int start = (currentPage - 1) * pageBean.getPageSize();
        int end = pageBean.getPageSize();
        //封装每页显示的数据
        List<SemiPhysicalEquipmentInfo> lists = hardWareMapper.findAllHardWare(start, end, equipmentId);
        if (!CollectionUtils.isEmpty(lists)) {
            for (SemiPhysicalEquipmentInfo info : lists) {
                List<SemiPhysicalUseInfo> useInfos = hardWareMapper.findAllUseInfo(info.getId());
                info.setUseInfos(useInfos);
                List<SemiPhysicalPerformanceValue> values = hardWareMapper.findAllPerformanceVal(info.getId());
                info.setPerformances(values);
            }
            pageBean.setLists(lists);
        } else {
            pageBean.setLists(null);
        }
        return pageBean;
    }

    @Override
    public int editHardWareById(SemiPhysicalEquipmentInfo semiPhysicalEquipmentInfo) {
        //修改装备信息
        int c = hardWareMapper.editHardWareById(semiPhysicalEquipmentInfo);
        List<SemiPhysicalUseInfo> useInfos = semiPhysicalEquipmentInfo.getUseInfos();
        //修改使用信息
        if (!CollectionUtils.isEmpty(useInfos)){
            for (SemiPhysicalUseInfo useInfo : useInfos) {
                c += hardWareMapper.editUseInfo(useInfo);
            }
        }
        List<SemiPhysicalPerformanceValue> values = semiPhysicalEquipmentInfo.getPerformances();
        //修改性能列表
        if (!CollectionUtils.isEmpty(values)) {
            for (SemiPhysicalPerformanceValue value : values) {
                c += hardWareMapper.editPerformanceValue(value);
            }
        }
        return c;
    }

    /**单独修改使用信息*/
    @Override
    public int editUseInfoById(SemiPhysicalUseInfo useInfo) {
        return hardWareMapper.editUseInfo(useInfo);
    }

    @Override
    public Boolean removeHardWareById(int[] ids) {
        //利用sql同时删除三张表关联数据
        int i = hardWareMapper.removeHardWareById(ids);
        if (i > 0) {
            return true;
        }
        return false;
    }

    /**
     * 通过装备id获取装备信息
     */
    @Override
    public SemiPhysicalEquipmentInfo findHardWareById(Integer id) {
        SemiPhysicalEquipmentInfo info = hardWareMapper.findHardWareById(id);
        List<SemiPhysicalUseInfo> useInfos = hardWareMapper.findAllUseInfo(id);
        List<SemiPhysicalPerformanceValue> values = hardWareMapper.findAllPerformanceVal(id);
        info.setUseInfos(useInfos);
        info.setPerformances(values);
        return info;
    }


    /**
     * 获取所有装备
     */
    @Override
    public List<SemiPhysicalEquipment> findAllEquipment() {
        return hardWareMapper.findAllEquipment();
    }

    /**
     * 获取所有性能
     */
    @Override
    public List<SemiPhysicalPerformance> findAllPerformances(Integer equipmentId) {
        return hardWareMapper.findAllPerformances(equipmentId);
    }

    @SneakyThrows
    @Override
    public void export(String startTime, String endTime){
        String fileName = title + ".xls";
        //所有装备
        List<SemiPhysicalEquipment> allEquipment = hardWareMapper.findAllEquipment();
        for (SemiPhysicalEquipment equipment : allEquipment) {
            String sheetName = equipment.getName();
            //所有装备详情
            //List<SemiPhysicalEquipmentInfo> equipmentInfoList= hardWareMapper.findAllEquipmentInfoById(equipment.getId());
            List<SemiPhysicalEquipmentInfo> equipmentInfoList= hardWareMapper.findAllInfoByIdAndTime(equipment.getId(),startTime,endTime);
            if(!CollectionUtils.isEmpty(equipmentInfoList)){
                //装备性能
                List<SemiPhysicalPerformanceValue> performanceList = hardWareMapper.findAllPerformanceVal(equipment.getId());
                String perfColumn = "主要性能,"+performanceList.size()+",1";
                //生成表头信息
                List<List<String>> headerList = generateHeader(perfColumn, performanceList);
                List<String> title1 = headerList.get(0);
                List<String> title2 = headerList.get(1);
                //填充表信息
                List<List<String>> column = fillTable(equipmentInfoList, performanceList);

                HSSFWorkbook wb = new ExcelUtils().getHSSFWorkbook(sheetName,title1,title2,column);
                fileName = new String(fileName.getBytes(),"ISO8859-1");
                response.setContentType("application/octet-stream;charset=ISO8859-1");
                response.setHeader("Content-Disposition","attachment;filename="+fileName);
                response.addHeader("Pargam","no-cache");
                response.addHeader("Cache-Control","no-cache");
                OutputStream os = response.getOutputStream();
                wb.write(os);
                os.flush();
                os.close();
            }
        }
    }

    /**
     * 封装表头信息
     * @return
     */
    private List<List<String>> generateHeader(String perfColumn,List<SemiPhysicalPerformanceValue> values){
        List<List<String>> headerList = new ArrayList<>();
        List<String> title1 = new ArrayList<String>(){
            {
                add("序号,1,2");add("装备信息,6,1");add(perfColumn);add("接口信息,2,1");
            }
        };
        List<String> title2 = new ArrayList<String>(){
            {
                add("半实物装备名称");add("装备类型");add("装备编号");
                add("研制单位");add("所属部队");add("可匹配模型");
                for (SemiPhysicalPerformanceValue value : values) {
                    add(value.getPerformanceName());
                }
                add("输入参数");add("输出参数");
            }
        };
        headerList.add(title1);
        headerList.add(title2);
        return headerList;
    }

    /**
     * 填充表内容
     * @return
     */
    private List<List<String>> fillTable(List<SemiPhysicalEquipmentInfo> infos,List<SemiPhysicalPerformanceValue> values){
        List<List<String>> column = new ArrayList<>();
        for (SemiPhysicalEquipmentInfo equipmentInfo : infos) {
            List<String> result = new ArrayList<String>(){
                {
                    add(equipmentInfo.getName());
                    add(equipmentInfo.getType());
                    add(equipmentInfo.getNumber());
                    add(equipmentInfo.getUnit());
                    add(equipmentInfo.getForces());
                    add(equipmentInfo.getMatchableModel());
                    for (SemiPhysicalPerformanceValue value : values) {
                        add(value.getPerformanceValue());
                    }
                    add(equipmentInfo.getInParam());
                    add(equipmentInfo.getOutParam());
                }
            };
            column.add(result);
        }
        return column;
    }

    /**
     * 导入Excel
     * @param file
     * @return
     */
    @Override
    public Boolean importExcel(MultipartFile file){
        int count = 0;
        try {
            Map<String,List<List<String>>> data = ExcelUtils.getFormatData(file);
            for (String equipmentName : data.keySet()) {
                SemiPhysicalEquipment equipment = hardWareMapper.getEquipmentByName(equipmentName);
                if (equipment != null) {
                    count += saveData(data.get(equipmentName), equipment);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (count == 0){
            return false;
        }
        return true;
    }

    private int saveData(List<List<String>> data,SemiPhysicalEquipment equipment) {
        int count = 0;
        //表头名 如装备名称、装备类型。。。
        List<String> title = data.get(0);
        for (int i = 1 ; i < data.size() ; i ++) {
            List<String> one = data.get(i);
            //固定列数 除性能外
            int typeNum = one.size() - 9;
            SemiPhysicalEquipmentInfo info = new SemiPhysicalEquipmentInfo();
            info.setName(one.get(1));
            info.setType(one.get(2));
            info.setNumber(one.get(3));
            info.setUnit(one.get(4));
            info.setForces(one.get(5));
            info.setMatchableModel(one.get(6));
            info.setInParam(one.get(6 + typeNum + 1));
            info.setOutParam(one.get(6 + typeNum + 2));

            info.setEquipmentId(equipment.getId());
            count += hardWareMapper.hardWareRegist(info);
            for (int j = 6 ; j < 7 + typeNum ; j ++) {
                SemiPhysicalPerformance performance = hardWareMapper.findPerByNameAndequipId(title.get(j),equipment.getId());
                if (!StringUtils.isEmpty(performance)) {
                    SemiPhysicalPerformanceValue value = new SemiPhysicalPerformanceValue();
                    value.setPerformanceId(performance.getId());
                    value.setPerformanceValue(one.get(j));
                    value.setEquipInfoId(info.getId());
                    count += hardWareMapper.insertPerformances(value);
                }
            }
        }
        return count;
    }
}
